// Console 해제
if(typeof window.console=='undefined'){window.console={log:function(){},error:function(){}}}else{var consoleAPI;if(typeof console._commandLineAPI!=='undefined'){console.API=console._commandLineAPI}else if(typeof console._inspectorCommandLineAPI!=='undefined'){console.API=console._inspectorCommandLineAPI}};

(function(window, undefined) {

console.log( "Macro version - 0.1.1" );

var Macro = (function() {
	var _self = null;
	var _queue = [];
	var _bindedCommands = {
		 "_delayMacro": {
		 	handler:function( time ) {
				setTimeout( _self.proxy(function() {
					_self.complete( "_delayMacro" );
				}), time );
			}
		},
		"_executeFunc": {
			handler:function( func, context ) {
		
				var args = Array.prototype.slice.call( arguments, 0 );
				args.shift();
				args.shift();
				
				func.apply( context, args );
				
				_self.complete( "_executeFunc" );
			}
		}
	};
	var _macroQueue = [];
	var _active = false;
	var _currentCommand = null;
	
	return ({
		proxy: function(handler) {
			var self = this;
			return (function() {
				return handler.apply( self, arguments );
			});
			
			return this;
		},
		
		//Controller Method
		bindCommand: function( commandName, handler, context ) {
			var self = _self = this;
			
			if ( ! this.hasCommand( commandName ) ) {
				_bindedCommands[commandName] = {
					handler:self.proxy(handler),
					context:context
				};
				return true;
			};
	
			return false;
		},
	
		unbindCommand: function( commandName, handler, context ) {
	
			if ( this.hasCommand( commandName ) ) {
				_bindedCommands[ commandName ] = undefined;
				return true;
			}
			return false;
		},
		
		hasCommand: function( commandName ) {
			return ( _bindedCommands[ commandName ] != undefined && _bindedCommands[ commandName ] != null ) ? true : false;
		},
	
		clearCommands: function() {
			for ( var name in _bindedCommands ) {
				_bindedCommands[ commandName ] = undefined;
			}
			
			_bindedCommands = [];
		},
	
		execute: function( commandName/*, …args*/ ) {
			if ( ! this.hasCommand( commandName ) ) {
				return;
			};
	
			var args = Array.prototype.slice.call( arguments, 0 );
			args.shift();
			
			var command = (_bindedCommands[ commandName ]);
			
			command.handler.apply( command.context, args );
		},
	
		//Macro Method
		addMacro: function( commandName/*, …args*/ ) {
			if ( this.hasCommand( commandName ) ) {
				if ( this.active == true ) {
					console.error( "now macro is active, but add macro command '" + commandName + "' " );
				}
				else {
					console.log( "add macro command '" + commandName + "' " );
				};
	
				var args = Array.prototype.slice.call( arguments, 0 );
				args.shift();
				
				_macroQueue.push( { commandName:commandName, arguments:args } );
	
				return;
			};
			
			console.error( "don't have command '" + commandName + "' " );
		},
	
		addExecuteMacro: function( handler/*, …args*/ ) {
			var args = Array.prototype.slice.call( arguments, 0 );
			args.shift();
	
			_macroQueue.push( { commandName:"_executeFunc", arguments:[ handler, args ] } );
		},
		
		startMacro: function() {
			if ( _macroQueue.length > 0 ) {
				if ( _active == true ) {
					console.error( "! macro is active - " + _currentCommand.commandName );
					return;
				};
				
				console.log( "start macro " );
				
				_active = true;
				
				this.nextMacro();
			};
		},
		
		completeMacro: function() {
			console.log( "** completed macro-commands **" );
			
			_active = false;
		},
		
		nextMacro: function() {
			if ( _active == true && _macroQueue.length > 0 ) {
				_currentCommand = _macroQueue.shift();
				
				if ( this.hasCommand( _currentCommand.commandName ) ) {
					console.log( "execute command '" + _currentCommand.commandName + "' " );
					
					var command = _bindedCommands[ _currentCommand.commandName ];
	
					command.handler.apply( command.context, _currentCommand.arguments );
					return true;
				};
				
				console.error( "don't have command '" + _currentCommand.commandName + "' " );
				return false;
			};
			
			this.completeMacro();
	
			return false;
		},
		
		clearMacro: function() {
			console.log( "macro clear " );
			
			_macroQueue = new Array();
			_active = false;
			_currentCommand = null;
		},
		
		complete: function( commandName, removeCommand ) {
			removeCommand = ( removeCommand == undefined ) ? false : removeCommand;
	
			if ( _active == false ) {
				return;
			};
				
			console.log( "complete command '" + commandName + "' " );
			
			if ( _currentCommand.commandName == commandName ) {
				this.nextMacro();
			};
			
			if ( removeCommand === true ) {
				this.removeCommand( commandName );
			};
		},
		
		delay: function( time ) {
			console.log( "add macro delay " );
	
			_macroQueue.push( { commandName:"_delayMacro", arguments:[time] } );
		},
		
		currentCommandName: function() {
			return ( ! _currentCommand ) ? null : _currentCommand.commandName;
		},
		
		active: function() {
			return _active;
		}
	});
});

window.Macro = Macro;

})(window);